package com.tianji.learning.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.po.ReplyDTO;
import com.tianji.learning.domain.po.ReplyPageQuery;
import com.tianji.learning.domain.vo.ReplyVO;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动问题的回答或评论 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-12-18
 */
@Service
public class InteractionReplyServiceImpl extends ServiceImpl<InteractionReplyMapper, InteractionReply> implements IInteractionReplyService {

    @Autowired
    private IInteractionQuestionService questionService;

    /**
     * 添加回复
     *
     * @param dto
     */
    @Override
    public void addReply(ReplyDTO dto) {
        //新增回复
        InteractionReply reply = BeanUtils.copyBean(dto, InteractionReply.class);
        boolean save = this.save(reply);
        if (!save) {
            throw new RuntimeException("添加回复失败");
        }
        //不存在上级回答id说明是评论
        if (dto.getAnswerId() == null) {
            //评论数+1
            this.lambdaUpdate().eq(InteractionReply::getId, dto.getAnswerId()).setSql("reply_times = reply_times + 1").update();
            //判断是否是学生提交
            if (dto.getIsStudent()) {
                //学生回复数+1
                //问题回复数+1
                questionService.lambdaUpdate().eq(InteractionQuestion::getId, dto.getQuestionId()).setSql("reply_times = reply_times + 1").update();
            }
        } else {
            //问题回复数+1
            questionService.lambdaUpdate().eq(InteractionQuestion::getId, dto.getQuestionId()).setSql("reply_times = reply_times + 1").set(InteractionQuestion::getLatestAnswerId, dto.getAnswerId()).update();
        }

    }

    /**
     * 管理端分页查询回复
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<ReplyVO> replyPageAdmin(ReplyPageQuery query) {
        //都为空，返回空
        if (ObjectUtils.isEmpty(query.getQuestionId()) && ObjectUtils.isEmpty(query.getAnswerId())) {
            return PageDTO.empty(0L, 0L);
        }

        PageDTO<ReplyVO> pageVo = PageDTO.empty(0L, 0L);

        //只查问题列表
        if (ObjectUtils.isNotEmpty(query.getQuestionId()) && ObjectUtils.isEmpty(query.getAnswerId())) {
            pageVo = justQueryAnswerList(query);
        }

        //只查评论列表
        if (ObjectUtils.isNotEmpty(query.getAnswerId()) && ObjectUtils.isEmpty(query.getQuestionId())) {
            pageVo = justQueryCommentList(query);
        }

        return pageVo;


    }


    @Autowired
    private UserClient userClient;

    /**
     * 只查问题列表
     *
     * @param query
     * @return
     */
    private PageDTO<ReplyVO> justQueryAnswerList(ReplyPageQuery query) {
        //分页查询
        Page<InteractionReply> replyPage = this.lambdaQuery().eq(InteractionReply::getQuestionId, query.getQuestionId()).orderByDesc(InteractionReply::getLikedTimes).orderByDesc(InteractionReply::getCreateTime).page(query.toMpPage());

        List<InteractionReply> replyList = replyPage.getRecords();
        //获取用户id集合
        List<Long> userIds = replyList.stream().map(InteractionReply::getUserId).collect(Collectors.toList());
        List<UserDTO> userDTOList = userClient.queryUserByIds(userIds);
        //转化为map
        Map<Long, UserDTO> userMap = new HashMap<>();
        if (ObjectUtils.isNotEmpty(userDTOList)) {
            userMap = userDTOList.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO -> UserDTO));
        }
        //封装属性返回
        ArrayList<ReplyVO> replyVOS = new ArrayList<>();
        for (InteractionReply reply : replyList) {
            ReplyVO replyVO = BeanUtils.copyBean(reply, ReplyVO.class);
            Long userId = reply.getUserId();
            UserDTO userDTO = userMap.get(userId);

            replyVO.setUserName(userDTO.getName());
            replyVO.setUserIcon(userDTO.getIcon());
            replyVO.setUserType(userDTO.getType());
            replyVOS.add(replyVO);
        }
        return PageDTO.of(replyPage, replyVOS);
    }

    /**
     * 只查评论列表
     *
     * @param query
     * @return
     */
    private PageDTO<ReplyVO> justQueryCommentList(ReplyPageQuery query) {
        Page<InteractionReply> replyPage = this.lambdaQuery().eq(InteractionReply::getAnswerId, query.getAnswerId()).orderByDesc(InteractionReply::getLikedTimes).orderByDesc(InteractionReply::getCreateTime).page(query.toMpPage());
        List<InteractionReply> replyList = replyPage.getRecords();
        //添加评论人id,以及回复目标人id
        ArrayList<Long> userIds = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(replyList)) {
            replyList.forEach(reply -> {
                userIds.add(reply.getUserId());
                userIds.add(reply.getTargetUserId());
            });
        }

        List<UserDTO> userDTOList = userClient.queryUserByIds(userIds);
        Map<Long, UserDTO> userMap = userDTOList.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO -> UserDTO));
        ArrayList<ReplyVO> replyVOS = new ArrayList<>();
        for (InteractionReply reply : replyList) {
            ReplyVO replyVO = BeanUtils.copyBean(reply, ReplyVO.class);
            Long userId = reply.getUserId();
            UserDTO userDTO = userMap.get(userId);
            replyVO.setUserName(userDTO.getName());
            replyVO.setUserIcon(userDTO.getIcon());
            replyVO.setUserType(userDTO.getType());
            replyVO.setTargetUserName(userMap.get(reply.getTargetUserId()).getName());
            replyVOS.add(replyVO);

        }
        return PageDTO.of(replyPage, replyVOS);
    }

    /**
     * 管理端根据id查询回复详情
     * @param id
     * @return
     */
    @Override
    public ReplyVO adminQueryById(Long id) {
        InteractionReply one = this.lambdaQuery()
                .eq(InteractionReply::getId, id).one();
        ReplyVO replyVO = BeanUtils.copyBean(one, ReplyVO.class);
        //补充数据
        UserDTO userDTO = userClient.queryUserById(one.getUserId());
        UserDTO userDTO1 = userClient.queryUserById(one.getTargetUserId());

        if(userDTO!=null && userDTO1!=null){
            replyVO.setUserName(userDTO.getName());
            replyVO.setUserType(userDTO.getType());
            replyVO.setUserIcon(userDTO.getIcon());
            replyVO.setTargetUserName(userDTO1.getName());
        }
        return replyVO;
    }

    /**
     * 管理端修改是否隐藏
     *
     * @param id
     * @param hidden
     */
    @Override
    public void hidden(Long id, Boolean hidden) {
        //先根据id查出来
        InteractionReply one = this.lambdaQuery()
                .eq(InteractionReply::getId, id)
                .one();

        if (ObjectUtils.isNotEmpty(one) && one.getAnswerId() == 0) {
            //回答，把该回答下的评论改了
            boolean update1 = this.lambdaUpdate()
                    .set(hidden != null, InteractionReply::getHidden, hidden)
                    .eq(InteractionReply::getAnswerId, id)
                    .update();
            //回答自己也更新
            boolean update2 = this.lambdaUpdate()
                    .set(hidden != null, InteractionReply::getHidden, hidden)
                    .eq(InteractionReply::getId, id)
                    .update();

            if (!update1 || !update2) {
                throw new BadRequestException("回答更新失败");
            }
        }

        if (ObjectUtils.isNotEmpty(one) && one.getAnswerId() != 0) {
            //评论
            boolean result = this.lambdaUpdate()
                    .set(hidden != null, InteractionReply::getHidden, hidden)
                    .update();
            if (!result) {
                throw new BadRequestException("评论更新失败");
            }
        }
    }

    /**
     * 分页查询回复信息
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<ReplyVO> replyPage(ReplyPageQuery query) {
        //1.先判断参数是否正确
        if (query.getQuestionId() == null && query.getAnswerId() == null) {
            return PageDTO.empty(0L, 0L);
        }

        PageDTO<ReplyVO> pageVo = PageDTO.empty(0L, 0L);

        //这个就是问题分页
        if (query.getQuestionId() != null && query.getAnswerId() == null) {
            pageVo = questionQuery(query);
        }

        if (query.getQuestionId() == null && query.getAnswerId() != null) {
            pageVo = answerQuery(query);
        }
        return pageVo;
    }

    /**
     * 分页
     * @param query
     * @return
     */
    private PageDTO<ReplyVO> answerQuery(ReplyPageQuery query) {
        Page<InteractionReply> replyPage = this.lambdaQuery()
                .eq(InteractionReply::getAnswerId, query.getAnswerId())
                .eq(InteractionReply::getHidden, false)
                .page(query.toMpPage("liked_times", false));
        List<InteractionReply> records = replyPage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return PageDTO.empty(replyPage);
        }
        Set<Long> targetUserIds = new HashSet<>();
        Set<Long> replyIds = new HashSet<>();
        Set<Long> questionIds = new HashSet<>();
        for (InteractionReply record : records) {
            if (!record.getAnonymity()) {
                questionIds.add(record.getUserId());
            }
            replyIds.add(record.getTargetUserId());
        }
        List<InteractionReply> replyList = lambdaQuery().in(InteractionReply::getUserId, replyIds).list();
        for (InteractionReply interactionReply : replyList) {
            if (!interactionReply.getAnonymity()) {
                targetUserIds.add(interactionReply.getUserId());
            }
        }
        List<UserDTO> questionUsers = userClient.queryUserByIds(questionIds);
        Map<Long, UserDTO> collect = questionUsers.stream().collect(Collectors.toMap(UserDTO::getId, x->x));
        List<UserDTO> replyUserS = userClient.queryUserByIds(targetUserIds);
        Map<Long, UserDTO> collect1 = replyUserS.stream().collect(Collectors.toMap(UserDTO::getId, x->x));
        List<ReplyVO> voList = new ArrayList<>();
        for (InteractionReply record : records) {
            ReplyVO replyVO = BeanUtils.copyBean(record, ReplyVO.class);
            if (collect.get(record.getUserId()) != null) {
                if (!record.getAnonymity()) {
                    replyVO.setUserName(collect.get(record.getUserId()).getName());
                    replyVO.setUserIcon(collect.get(record.getUserId()).getIcon());
                }
            }
            if (collect1.get(record.getTargetUserId()) != null) {
                replyVO.setTargetUserName(collect1.get(record.getTargetUserId()).getName());
            }
            voList.add(replyVO);
        }
        return PageDTO.of(replyPage, voList);


    }

    /**
     * 问题分页
     * @param query
     * @return
     */
    private PageDTO<ReplyVO> questionQuery(ReplyPageQuery query) {

        Page<InteractionReply> questionPage = this.lambdaQuery()
                .eq(InteractionReply::getQuestionId, query.getQuestionId())
                .eq(InteractionReply::getHidden, false)
                .page(query.toMpPage("liked_times", false));
        //如果是空的话,直接返回
        List<InteractionReply> records = questionPage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return PageDTO.empty(questionPage);
        }
        Set<Long> questionIds = new HashSet<>();
        //如果不是匿名,添加到集合中
        for (InteractionReply record : records) {
            if (!record.getAnonymity()) {
                questionIds.add(record.getUserId());
            }
        }
        List<UserDTO> queryQuestionByIds = userClient.queryUserByIds(questionIds);
        Map<Long, UserDTO> collect = queryQuestionByIds.stream().collect(Collectors.toMap(UserDTO::getId, x->x));
        List<ReplyVO> voList = new ArrayList<>();
        for (InteractionReply record : records) {
            UserDTO userInfo = collect.get(record.getUserId());
            ReplyVO replyVO = BeanUtils.copyBean(record, ReplyVO.class);
            if (ObjectUtil.isNotEmpty(userInfo)) {
                if (!record.getAnonymity()) {
                    replyVO.setUserName(userInfo.getName());
                    replyVO.setUserIcon(userInfo.getIcon());
                }
            }
            voList.add(replyVO);
        }
        return PageDTO.of(questionPage, voList);
    }

}
